<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function a(){       //外层函数，闭包函数
            var n=0;         //私有变量，在函数内部定义，局部作用域，出a函数就用不了了

            function b(m){  //内部函数，私有函数，局部作用域，出a函数就用不了了
                n=n + m;       //加上内部函数b的变量，相当于复合函数
                return n;    //b函数发出输出n的命令，在b的二层局部作用域
            }               //退出b，进入a的一层局部作用域

            return b();       //a函数发出输出b的命令（没意思啊，就是简单的解开套娃而已）
        }                    //然后n、m在a中全部被销毁。
        var c=a();           //定义函数c的值为函数a。（c调用了外层函数a，a返回内部函数b，所以c的值实际上是a的值,a的值实际上是b的值，b的值实际上是n的值）
        document.write(n);//第一次调用函数b，令m=3，则a令n=0（n）+3（m）=3。再有b=n,a=b,c=a（因为脚本语言是逐行执行代码，所以b本来在里面，又跑到外面去了。输出c=a=b=n=3
        document.write(c);/*第二次调用函数b，令m=3，则a令n=3（n）+3（m）=6，再有b=n,a=b,c=a，输出c=a=b=n=6.
                            （发现了，这就是a为闭包函数的作用，如果a不为闭包函数，那么b这个私有变量就在局部作用域a执行完毕后自动销毁，所以不能实现递增效果）*/
        document.write(c);
        document.write(typeof(a()))
      /*说明一下其它几种情况：
      1、把第二个b改成c，结果不变，说明第二个b并不是第一个b
      2、把第二个b删掉，把document里改成a，结果输出错误，因为a是无参数函数，只提供计算。
      3、但是c=a()，此时c可以给形参赋值，而且赋的形参是m，原因是：a()不是a这个函数，而是a函数的返回值，也就是b。b是函数，可以赋形参m值，所以c是函数b，可以赋形参m值。
      4、那为什么n的值保留了下来呢？因为这里的全局变量c调用了b函数整体，所以b的形参跳出了a，进入了全局。所以n成了全局变量。这也就是“闭包”的意思：利用了JS的一个BUG：变量并不会在脱离函数后立即销毁，而是在第一次调用函数后才销毁。所以如果你在下一个语句中立刻调用那个内部函数，可以把它变成全局变量，从而保留下来。
      */
    </script>
</body>
</html>